﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Effects.Wave
{

    /// <summary>
    ///  Converts among sample index, time and string describing time.
    /// </summary>
    /// <remarks>
    ///  <para>
    ///     This class converts from sample index to DateTime (only min,secs, milis contains useful information)  and back. 
    ///     It provides only approx calculations.
    ///  </para>
    ///  <para>
    ///   Adding to this it also converts from ,both DateTime and sample index to formated string and backwards.
    ///   Formated string is string in format minutes:seconds:miliseconds which is used to be displayed to the user.
    ///  </para>
    /// </remarks>
    public class TimeSampleConverter
    {
        /// <summary>
        ///  Converts given sample index to <see cref="DateTime"/> information
        /// </summary>
        /// <param name="sample"> Sample index </param>
        /// <param name="sampleRate"> Sample rate of the data </param>
        /// <param name="channels"> Channels count </param>
        /// <returns> Date time storing time of the sample.  </returns>
        public static DateTime SampleToTime(int sample, int sampleRate, int channels)
        {
             int time = sample / channels;
            int milis = time * 1000 / sampleRate;

            int minutes = milis / 60000;
            milis %= 60000;

            int secs = milis / 1000;
            milis %= 1000;

            return new DateTime(1955, 9, 30, 0, minutes, secs, milis);
        }

        /// <summary>
        ///  Converts from <see cref="DateTime"/> time infromation to sample index.
        /// </summary>
        /// <param name="time"> Time informatione - only minutes, seconds and miliseconds are used. </param>
        /// <param name="sampleRate"> Sample rate of the data </param>
        /// <param name="channels"> Channels count </param>
        /// <returns> Sample index </returns>
        public static int TimeToSample(DateTime time,int sampleRate,int channels)
        {
            int milis = time.Millisecond + 1000 * time.Second + 60000 * time.Minute;

            int sample = milis * sampleRate / 1000;
            sample *= channels;

            return sample;
        }

        /// <summary>
        ///  Converts sample to formated string.
        /// </summary>
        /// <param name="sample"> Sample index </param>
        /// <param name="sampleRate"> Sample rate of the data </param>
        /// <param name="channels"> Channels count </param>
        /// <returns> Formated string </returns>
        public static string SampleToString(int sample,int sampleRate,int channels)
        {
            DateTime time = SampleToTime(sample, sampleRate, channels);
            return TimeToString(time);
        }

        /// <summary>
        ///  Converts DateTime to formated string
        /// </summary>
        /// <param name="time"> Time informatione - only minutes, seconds and miliseconds are used. </param>
        /// <returns> formated string </returns>
        public static string TimeToString(DateTime time)
        {
            return time.Minute.ToString() + ":" + time.Second.ToString() + ":" + time.Millisecond.ToString();
        }

        /// <summary>
        ///  Converts formated string to time.
        /// </summary>
        /// <param name="s"> Formated string </param>
        /// <returns> Time informatione - only minutes, seconds and miliseconds are used. </returns>
        public static DateTime StringToTime(string s)
        {
            string[] split = s.Split(new char[] { ':' });

            int min = Convert.ToInt32(split[0]);
            if (min < 0) throw new IndexOutOfRangeException();

            int secs = Convert.ToInt32(split[1]);
            if (secs < 0 || secs > 59) throw new IndexOutOfRangeException();

            int milis = Convert.ToInt32(split[2]);
            if (milis < 0 || milis > 999) throw new IndexOutOfRangeException();

            return new DateTime(1955, 9, 30, 0, min, secs, milis);
        }

        /// <summary>
        ///  Converts formated string to sample.
        /// </summary>
        /// <param name="s"> formated string </param>
        /// <param name="sampleRate"> Sample rate of the data </param>
        /// <param name="channels"> Channels count </param>
        /// <returns> Sample index </returns>
        public static int StringToSample(string s, int sampleRate,int channels)
        {
            return TimeToSample(StringToTime(s), sampleRate, channels);
        }
    }
}
